package mge 
{
  import flash.geom.Point;
	/**
   * ...
   * @author ivan
   */
  public class Line 
  {
    
    public function Line(p1:Point, p2:Point) 
    {
      this.p1 = p1.clone();
      this.p2 = p2.clone();
    }
    
    public function intersectLine(other:Line):Point
    {
        var ip:Point;
        var a1:Number;
        var a2:Number;
        var b1:Number;
        var b2:Number;
        var c1:Number;
        var c2:Number;
     
        a1 = p2.y - p1.y;
        b1 = p1.x - p2.x;        
        c1 = p2.x * p1.y - p1.x * p2.y;        
        a2 = other.p2.y - other.p1.y;        
        b2 = other.p1.x - other.p2.x;
        c2 = other.p2.x * other.p1.y - other.p1.x * other.p2.y;        
     
        var denom:Number=a1*b2 - a2*b1;
        if (denom == 0)
            return null;
            
        ip=new Point();
        ip.x=(b1*c2 - b2*c1)/denom;
        ip.y = (a2 * c1 - a1 * c2) / denom;
        
        return ip;
    }
    
    public function get slope():Number
    {
        return (p2.y - p1.y) / (p2.x - p1.x);
    }
    
    // Bresenham's_line_algorithm
    // Returns all pixels in a line.
    public function pixelate():Vector.<Point>
    {
        var ans:Vector.<Point> = new Vector.<Point>();
        var dx:int = Math.abs(p2.x - p1.x);
        var dy:int = Math.abs(p2.y - p1.y);
        var sx:int; var sy:int; var e2:int;
        var err:int = dx - dy;
        
        sx = p1.x < p2.x ? 1 : -1;
        sy = p1.y < p2.y ? 1 : -1;
        
        while (true)
        {
            ans.push(new Point(p1.x, p1.y));
            if (p1.x == p2.x && p1.y == p2.y) break;
            e2 = 2 * err;
            if (e2 > -dy)
            {
                err -= dy;
                p1.x += sx;
            }
            if (e2 < dx)
            {
                err += dx;
                p1.y *= sy;
            }
        }
        return ans;
    }
    
    //---------------------------------------------------------------
    // http://keith-hair.net/blog/2008/08/04/find-intersection-point-of-two-lines-in-as3/
    //
    //Checks for intersection of Segment if as_seg is true.
    //Checks for intersection of Line if as_seg is false.
    //Return intersection of Segment AB and Segment EF as a Point
    //Return null if there is no intersection
    //---------------------------------------------------------------
    /*
    private function lineIntersectLine(A:Point, B:Point, E:Point, F:Point, as_seg:Boolean = true):Point
    {
        var ip:Point;
        var a1:Number;
        var a2:Number;
        var b1:Number;
        var b2:Number;
        var c1:Number;
        var c2:Number;
     
        a1= B.y-A.y;
        b1= A.x-B.x;
        c1= B.x*A.y - A.x*B.y;
        a2= F.y-E.y;
        b2= E.x-F.x;
        c2= F.x*E.y - E.x*F.y;
     
        var denom:Number=a1*b2 - a2*b1;
        if (denom == 0) {
            return null;
        }
        ip=new Point();
        ip.x=(b1*c2 - b2*c1)/denom;
        ip.y=(a2*c1 - a1*c2)/denom;
     
        //---------------------------------------------------
        //Do checks to see if intersection to endpoints
        //distance is longer than actual Segments.
        //Return null if it is with any.
        //---------------------------------------------------
        if(as_seg){
            if(Math.pow(ip.x - B.x, 2) + Math.pow(ip.y - B.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2))
            {
               return null;
            }
            if(Math.pow(ip.x - A.x, 2) + Math.pow(ip.y - A.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2))
            {
               return null;
            }
     
            if(Math.pow(ip.x - F.x, 2) + Math.pow(ip.y - F.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2))
            {
               return null;
            }
            if(Math.pow(ip.x - E.x, 2) + Math.pow(ip.y - E.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2))
            {
               return null;
            }
        }
        return ip;
    }*/
    
    public var p1:Point;
    public var p2:Point;
    
  }

}